package com.lemon.exam.common.redis.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * Redis Set 操作 类对象
 *
 * @author Lemon
 * @since 2025/7/4 18:06
 */
public final class SetOperations extends BaseOperations {
    public SetOperations(ObjectMapper objectMapper, ReactiveRedisTemplate<String, Object> template) {
        super(objectMapper, template);
    }

    /**
     * 添加元素
     *
     * @param key    键
     * @param values 值
     * @return 是否成功
     */
    public Mono<Boolean> add(String key, Object... values) {
        return withRetry(
                template.opsForSet().add(key, values).map(v -> v != null && v == values.length),
                "redis set add key: %s".formatted(key)
        ).onErrorResume(err -> Mono.just(false));
    }

    /**
     * 获取元素
     *
     * @param key 键
     * @return 元素
     */
    public <T> Flux<T> get(String key, Class<T> clazz) {
        return withRetry(
                template.opsForSet().members(key).mapNotNull(toGeneric(clazz)),
                "redis set get key: %s".formatted(key)
        ).onErrorResume(err -> Flux.empty());
    }

    /**
     * 删除元素
     *
     * @param key    键
     * @param values 值
     * @return 是否成功
     */
    public Mono<Boolean> del(String key, Object... values) {
        return withRetry(
                template.opsForSet().remove(key, values).map(v -> v != null && v == values.length),
                "redis set del key: %s".formatted(key)
        ).onErrorResume(err -> Mono.just(false));
    }
}
